package com.pricl.biz.util;



import java.io.ByteArrayInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.Bucket;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectResult;
import com.pricl.biz.file.entity.FileInfo;

import net.sf.ehcache.util.PropertyUtil;

/**
 * 阿里云OSS(对象存储服务)操作工具
 * @author chenhe
 *
 */
public class OSSUtils {
	// 日志对象
	public static final Logger logger = LoggerFactory.getLogger(OSSUtils.class);

	// 阿里云API的内或外网域名
	private static String ENDPOINT = null;
																		
	// 阿里云API的密钥Access Key ID
	private static String ACCESS_KEY_ID = null;
	// 阿里云API的密钥Access Key Secret
	private static String ACCESS_KEY_SECRET = null;
	//存储对象空间名
	private static String BUCKET_NAME = null;
	//配置文件
	 private static Properties props;
	 //init static datas
	 static{
		 
		 loadProps();
//	 ResourceBundle bundle =
//	 PropertyResourceBundle.getBundle("ossconfig.properties");
//	 ENDPOINT = bundle.containsKey("oss.endpoint") == false ? "" :
//	 bundle.getString("oss.endpoint");
//	 ACCESS_KEY_ID = bundle.containsKey("oss.accessKeyId") == false? "" :
//	 bundle.getString("oss.accessKeyId");
//	 ACCESS_KEY_SECRET = bundle.containsKey("oss.accessKeySecret") == false ? "" :
//	 bundle.getString("oss.accessKeySecret");
	 }
	 synchronized static private void loadProps(){
	         props = new Properties();
	        InputStream in = null;
	        try {
         //<!--第一种，通过类加载器进行获取properties文件流-->
	            in = PropertyUtil.class.getClassLoader().getResourceAsStream("ossconfig.properties");
           // <!--第二种，通过类进行获取properties文件流-->
	            //in = PropertyUtil.class.getResourceAsStream("/jdbc.properties");
	            props.load(in);
	            ENDPOINT =  props.getProperty("oss.endpoint");
	            ACCESS_KEY_ID =  props.getProperty("oss.accessKeyId");
	            ACCESS_KEY_SECRET = props.getProperty("oss.accessKeySecret");
	            BUCKET_NAME = props.getProperty("oss.bucketName");
	        } catch (FileNotFoundException e) {
	            logger.error("ossconfig.properties文件未找到");
	        } catch (IOException e) {
	            logger.error("出现IOException");
	        } finally {
	            try {
	                if(null != in) {
	                    in.close();
	                }
	            } catch (IOException e) {
	                logger.error("ossconfig.properties文件流关闭出现异常");
	            }
	        }
	        logger.info("properties文件内容：" + props);
	 }

	 
	/**
	 * 获取阿里云OSS客户端对象
	 */
	public static final OSSClient getOSSClient() {
		if(props == null){
			loadProps();
		}
		return new OSSClient(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);
	}

	/**
	 * 新建Bucket --Bucket权限:私有
	 * 
	 * @param bucketName
	 *            bucket名称
	 * @return true 新建Bucket成功
	 */
	public static final boolean createBucket(OSSClient client) {
		Bucket bucket = client.createBucket(BUCKET_NAME);
		return BUCKET_NAME.equals(bucket.getName());
	}

	/**
	 * 删除Bucket
	 * 
	 * @param bucketName
	 *            bucket名称
	 */
	public static final void deleteBucket(OSSClient client) {
		client.deleteBucket(BUCKET_NAME);
		System.out.println("删除" + BUCKET_NAME + "Bucket成功");
	}

	/**
	 * 向阿里云的OSS存储中存储文件 --file也可以用InputStream替代
	 * 
	 * @param client
	 *            OSS客户端
	 * @param file
	 *            上传文件
	 * @param bucketName
	 *            bucket名称
	 * @param diskName
	 *            上传文件的目录 --bucket下文件的路径
	 * @return String 唯一MD5数字签名
	 */
	public static final String uploadObject2OSS(OSSClient client,MultipartFile mpf,String fileUploadFullDirectory,String newFilename) {
		String resultStr = null;
		try {
			//要上传文件的数据流
			InputStream is = mpf.getInputStream();
			String fileName = mpf.getOriginalFilename();
			Long fileSize = mpf.getSize();
			// 创建上传Object的Metadata
			ObjectMetadata metadata = new ObjectMetadata();
			metadata.setContentLength(is.available());
			metadata.setCacheControl("no-cache");
			metadata.setHeader("Pragma", "no-cache");
			metadata.setContentEncoding("utf-8");
			metadata.setContentType(mpf.getContentType());//文件类型设置 getContentType(newFilename)
			metadata.setContentDisposition("filename/filesize=" + fileName + "/" + fileSize + "Byte.");
			//去掉路径第一个/字符
			String newFileUploadFullDirectory = fileUploadFullDirectory.substring(1,fileUploadFullDirectory.length());
			// 上传文件
			PutObjectResult putResult = client.putObject(BUCKET_NAME, newFileUploadFullDirectory + newFilename, is, metadata);
			// 解析结果
			resultStr = putResult.getETag();
		} catch (Exception e) {
			logger.info("上传阿里云OSS服务器异常." + e.getMessage());
		}
		return resultStr;
	}

	
	/**
	 * 向阿里云的OSS存储中存储文件 --file也可以用InputStream替代
	 * 
	 * @param client
	 *            OSS客户端
	 * @param file
	 *            上传文件
	 * @param bucketName
	 *            bucket名称
	 * @param diskName
	 *            上传文件的目录 --bucket下文件的路径
	 * @return String 唯一MD5数字签名
	 */
	public static final String uploadObject2OSS2(OSSClient client,FileInfo ofile, InputStream in , long length) {
		String resultStr = null;
		try {
			// 创建上传Object的Metadata
			ObjectMetadata metadata = new ObjectMetadata();
			// 设置上传文件长度
			metadata.setContentLength(in.available());
			metadata.setCacheControl("no-cache");
			metadata.setHeader("Pragma", "no-cache");
			metadata.setContentEncoding("utf-8");
			metadata.setContentType(ofile.getContentType());//文件类型设置 getContentType(newFilename)
			metadata.setContentDisposition("filename/filesize=" + ofile.getOname() + "/" + length + "Byte.");
			//去掉路径第一个/字符
			String newFileUploadFullDirectory = ofile.getPath().substring(1,ofile.getPath().length());
			String path = newFileUploadFullDirectory +"/" +ofile.getId()+"."+ofile.getExtName();
			// 上传文件
			PutObjectResult putResult = client.putObject(BUCKET_NAME, path, in, metadata);
			// 解析结果
			resultStr = putResult.getETag();
			//关闭流
		} catch (Exception e) {
			System.out.println(e.getMessage());
			logger.info("上传阿里云OSS服务器异常." + e.getMessage());
		}
		return resultStr;
	}
	
	
	/**
	 * 根据key获取OSS服务器上的文件输入流
	 * 
	 * @param client
	 *            OSS客户端
	 * @param bucketName
	 *            bucket名称
	 * @param diskName
	 *            文件路径
	 * @param key
	 *            Bucket下的文件的路径名+文件名
	 */
	public static final InputStream getOSS2InputStream(OSSClient client, String filePath) {
		OSSObject ossObj = client.getObject(BUCKET_NAME, filePath);
		return ossObj.getObjectContent();
	}

	/**
	 * 根据key删除OSS服务器上的文件
	 * 
	 * @param client
	 *            OSS客户端
	 * @param bucketName
	 *            bucket名称
	 * @param diskName
	 *            文件路径
	 * @param key
	 *            Bucket下的文件的路径名+文件名
	 */
	public static void deleteFile(OSSClient client, String filePath) {
		client.deleteObject(BUCKET_NAME, filePath);
		logger.info("删除" + BUCKET_NAME + "下的文件" + filePath + "成功");
	}

	/**
	 * 
	 * @param client
	 *            OSS客户端
	 * @param bucketName
	 *            bucket名称
	 * @param folderName
	 *            文件夹名称
	 */
	public static void createFolder(OSSClient client, String folderName) {

		client.putObject(BUCKET_NAME, folderName, new ByteArrayInputStream(new byte[0]), null);
	}

	/**
	 * 通过文件名判断并获取OSS服务文件上传时文件的contentType
	 * 
	 * @param fileName
	 *            文件名
	 * @return 文件的contentType
	 */
	public static final String getContentType(String fileName) {
		String fileExtension = fileName.substring(fileName.lastIndexOf(".") + 1);
		if ("bmp".equalsIgnoreCase(fileExtension))
			return "image/bmp";
		if ("gif".equalsIgnoreCase(fileExtension))
			return "image/gif";
		if ("png".equalsIgnoreCase(fileExtension))
			return "image/png";
		if ("jpeg".equalsIgnoreCase(fileExtension) || "jpg".equalsIgnoreCase(fileExtension)
				|| "png".equalsIgnoreCase(fileExtension))
			return "image/jpeg";
		if ("html".equalsIgnoreCase(fileExtension))
			return "text/html";
		if ("txt".equalsIgnoreCase(fileExtension))
			return "text/plain";
		if ("vsd".equalsIgnoreCase(fileExtension))
			return "application/vnd.visio";
		if ("ppt".equalsIgnoreCase(fileExtension) || "pptx".equalsIgnoreCase(fileExtension))
			return "application/vnd.ms-powerpoint";
		if ("doc".equalsIgnoreCase(fileExtension) || "docx".equalsIgnoreCase(fileExtension))
			return "application/msword";
		if ("xml".equalsIgnoreCase(fileExtension))
			return "text/xml";
		if ("zip".equalsIgnoreCase(fileExtension))
			return "application/octet-stream";
		return "text/html";
	}

}